using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;

namespace AdvancedInspector
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface, Inherited = false)]
	public class DescriptorAttribute : Attribute, IRuntimeAttribute, IRuntimeAttribute<DescriptorAttribute>
	{
		public delegate DescriptorAttribute DescriptorDelegate();

		private static Color TRANSPARENT = new Color(0f, 0f, 0f, 0f);

		private string name = string.Empty;

		private string description = string.Empty;

		private string url = string.Empty;

		private Texture icon;

		private Color color = Color.clear;

		private string methodName = string.Empty;

		private List<Delegate> delegates = new List<Delegate>();

		public string Name
		{
			get
			{
				return name;
			}
			set
			{
				name = value;
			}
		}

		public string Description
		{
			get
			{
				return description;
			}
			set
			{
				description = value;
			}
		}

		public string URL
		{
			get
			{
				return url;
			}
			set
			{
				url = value;
			}
		}

		public Texture Icon
		{
			get
			{
				return icon;
			}
			set
			{
				icon = value;
			}
		}

		public Color Color
		{
			get
			{
				return color;
			}
			set
			{
				color = value;
			}
		}

		public string MethodName
		{
			get
			{
				return methodName;
			}
		}

		public Type Template
		{
			get
			{
				return typeof(DescriptorDelegate);
			}
		}

		public List<Delegate> Delegates
		{
			get
			{
				return delegates;
			}
			set
			{
				delegates = value;
			}
		}

		public DescriptorAttribute()
		{
		}

		public DescriptorAttribute(string methodName)
		{
			this.methodName = methodName;
		}

		public DescriptorAttribute(float r, float g, float b)
			: this(string.Empty, string.Empty, string.Empty, r, g, b, 1f)
		{
		}

		public DescriptorAttribute(string name, string description)
			: this(name, description, string.Empty, 0f, 0f, 0f, 0f)
		{
		}

		public DescriptorAttribute(string name, string description, string url)
			: this(name, description, url, 0f, 0f, 0f, 0f)
		{
		}

		public DescriptorAttribute(string name, string description, string url, float r, float g, float b)
			: this(name, description, url, r, g, b, 1f)
		{
		}

		private DescriptorAttribute(string name, string description, string url, float r, float g, float b, float a)
		{
			this.name = name;
			this.description = description;
			this.url = url;
			color = new Color(r, g, b, a);
		}

		public DescriptorAttribute(string name, string description, Texture icon)
			: this(name, description, icon, TRANSPARENT)
		{
		}

		public DescriptorAttribute(string name, string description, Texture icon, Color color)
		{
			this.name = name;
			this.description = description;
			this.icon = icon;
			this.color = color;
		}

		public DescriptorAttribute Invoke(int index)
		{
			if (delegates.Count == 0 || index >= delegates.Count)
			{
				return this;
			}
			try
			{
				return delegates[0].DynamicInvoke() as DescriptorAttribute;
			}
			catch (Exception innerException)
			{
				if (innerException is TargetInvocationException)
				{
					innerException = ((TargetInvocationException)innerException).InnerException;
				}
				Debug.LogError(string.Format("Invoking a method to retrieve a Destriptor attribute failed. The exception was \"{0}\".", innerException.Message));
				return null;
			}
		}

		public static DescriptorAttribute GetDescriptor(Type type)
		{
			object[] customAttributes = type.GetCustomAttributes(typeof(DescriptorAttribute), true);
			if (customAttributes.Length == 0)
			{
				return null;
			}
			return customAttributes[0] as DescriptorAttribute;
		}

		public static List<DescriptorAttribute> GetDescriptors(List<Type> types)
		{
			List<DescriptorAttribute> list = new List<DescriptorAttribute>();
			foreach (Type type in types)
			{
				list.Add(GetDescriptor(type));
			}
			return list;
		}
	}
}
